package utils;

import enums.Direction;
import enums.PlayerColor;
import enums.Revealed;
import enums.Weapon;
import utils.Piece;


/**
 * Represents each piece on the board (Including the flags, traps and even empty cells on the board contain pieces that are marked as empty)
 */
public class Piece
{
	private static final String DIRECTORY_PIECE_IMAGE = "res\\";
	
	public Weapon weapon;
	public PlayerColor color;
	public Direction direction;
	public Revealed revealed;
	public static final int EMPTY = 12345;
	
	public static final int PlayerColorPosition = 0;
	public static final int DirectionPosition = 1;
	public static final int WeaponPosition = 2;
	public static final int RevealedPosition = 3;
	
	public  static final int WIN  =  1;
	public  static final int TIE  =  0;
	public  static final int LOSE = -1;
	private static final int[][] CombatRules = {{ TIE, LOSE,  WIN, WIN, LOSE},
												{ WIN,  TIE, LOSE, WIN, LOSE},
											    {LOSE,  WIN,  TIE, WIN, LOSE},
												{LOSE, LOSE, LOSE, TIE,  TIE},
												{ WIN,  WIN,  WIN, TIE,  TIE} };
										  // ROCK , PAPER , SCISSORS , FLAG , TRAP
	
	
	public Piece(String map)
	{
		setPiece(map);
	}		
	
	public Piece(PlayerColor color, Direction direction, Weapon weapon, Revealed revealed)
	{
		setPiece(color, direction, weapon, revealed);
	}
	
	public Piece(int specialValue)
	{
		setPiece(specialValue);
	}

	
	public String getMap () {
		String color = String.valueOf(this.color.ordinal());
		String direction = String.valueOf(this.direction.ordinal());
		String weapon = String.valueOf(this.weapon.ordinal());
		String revealed = String.valueOf(this.revealed.ordinal());
		
		return color + direction + weapon + revealed; 
	}
	
	public static String changeProperty(String map , int position , int value) {
		return map.substring(0, position) + value + map.substring(position+1);
	}
	
	public boolean isEmptyPiece()
	{
		return ((color == PlayerColor.NONE) && (direction == Direction.NONE) && (weapon == Weapon.NONE));
	}
	
	public String filePosition()
	{
		return DIRECTORY_PIECE_IMAGE + this.color.toString()  + " " + this.direction.toString() + " " +
						   			   this.weapon.toString() + " " + this.revealed.toString()  + Settings.IMAGES_FILE_EXTENSION;
	}
	
	public void setPiece(String map) {
		this.color = PlayerColor.Convert(Utils.charToInt(map.charAt(PlayerColorPosition)));
		this.direction = Direction.Convert(Utils.charToInt(map.charAt(DirectionPosition)));
		this.weapon = Weapon.Convert(Utils.charToInt(map.charAt(WeaponPosition)));
		this.revealed =  Revealed.Convert(Utils.charToInt(map.charAt(RevealedPosition)));
	}
	
	public void setPiece(PlayerColor color, Direction direction, Weapon weapon, Revealed revealed) {
		this.color = color;
		this.direction = direction;
		this.weapon = weapon;
		this.revealed = revealed;
	}
	
	public void setPiece(int specialValue) {
		if (specialValue == EMPTY) {
			this.color = PlayerColor.NONE;
			this.direction = Direction.NONE;
			this.weapon = Weapon.NONE;
			this.revealed = Revealed.NONE;
		}
	}

	public static int getProperty (String map , int property) {
		return Integer.valueOf(String.valueOf(map.charAt(property)));
	}
	
	/** 
	 * Returns the result of the battle (WIN, TIE or LOSE) between the "this" piece and the given piece
	 * 
	 * @param pieceEnemy - The given pieces that the "this" piece should battle.
	 * 
	 * @return An int representing the result of the battle : <br>
	 * 		   WIN - If the "this" piece wins. <br>
	 * 		   TIE - If there is a tie. <br>
	 * 		   LOSE - If the "this" piece loses. <br>
	 */
	public int battle(Piece pieceEnemy)
	{
		return CombatRules[weapon.ordinal()][pieceEnemy.weapon.ordinal()]; 
	}
}
